package Concurrency2.Chapter01_Base;

/**
 * Instruction：Thread的主要属性和方法
 * 注意该篇代码主要用于展示Thread的属性和方法, 运行会出现问题!!!
 * Author：@author MaLi
 */
public class Topic02_Thread {
    public static void main(String[] args) {
        // 定义一个线程任务, 并放入到Thread中
        Thread someThread = new Thread(() -> {
            //这里代表的是Runnable的run(), 在lambda表达式中定义线程任务的逻辑
            // 线程内部获取线程的方式
            Thread currentThread = Thread.currentThread();

            boolean daemon = currentThread.isDaemon();

        });
        //先开启线程, 然后做下面的测试
        someThread.start();

        //(一)线程的常见属性
        //1.1 线程ID
        long threadId = someThread.getId();
        //1.2 线程名
        String threadName = someThread.getName();
        //1.3 线程状态
        Thread.State threadState = someThread.getState();
        //1.4 线程优先级
        int threadPriority = someThread.getPriority();
        //1.5 线程所属线程组
        ThreadGroup threadGroup = someThread.getThreadGroup();

        //(二)线程的常见方法
        //2.1 设置守护线程
        someThread.setDaemon(false);
        boolean isDaemon = someThread.isDaemon();

        //2.2 开启线程
        someThread.start(); //OS调用定义的run()方法, 一个线程只能start()一次, 否则会抛异常

        //2.3 当前线程等待someThread执行
        try {
            //永远等待直到someThread执行完成
            someThread.join();
            //等待1000millis
            someThread.join(1000);
            //等待1000millis+100nanos
            someThread.join(1000, 100);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

        //2.4 中断执行
        someThread.interrupt();
        //判断是否被中断
        someThread.isInterrupted();
    }
}

/*
    重点:
    1, 如何开启线程
        start()
        但是在最佳实践中, 直接把创建好的线程任务提交给线程池去执行.
        线程池内的线程(暂且成为工作线程), 工作线程负责在队列中取出Runnable任务, 依次执行
        工作线程的初始化启动, 由线程池start()启动. 所以我们不使用start(), 不代表start()一点用处没有.

    2, 如何优雅的关闭线程
        interrupt(): 先标记为interruped

    3, 守护线程的作用
        一般为非守护线程服务的, 例如, 虚拟机的GC线程即守护线程, 加入应用程序线程都已经停止了, GC线程的存在也没有意义了.
        所以, 当非守护线程停止后, 守护线程也随机停止

    4, 线程的状态Thread.State, 参见java.lang.Thread.State源码
        new: new Thread(), 还未start()执行
        runnable : start(), 两个状态:1,等待OS给分配时间片; 2, 已经获取到CPU时间片
        blocked: 等待锁
        waiting: 本质是进入到等待队列
            Object.wait()
            Thread.join()
            LockSupport.park()
        timed_waiting: 有限等待
            Thread.sleep(timeout)
            Object.wait(timeout)
            Thead.join(timeout)
            LockSupport.parkNanos
            LockSupport.parkUntil
        terminated: 完成了执行(1, run中的逻辑执行完; 2, 异常退出)

     5, 线程优先级
        1 -- 10, 默认是5
        优先级高的, 即获取到CPU时间片的概率更大

     6, 线程组的作用
        统一管理线程组内的线程
        包括基本的添加和删除组内的线程
        中断组内的线程
        使用场景:
            定义一个线程组去执行任务, 假如一个线程失败, 让其它所有的线程都中断
        问题:
            在线程池中, 如何处理这种场景问题.
 */
